import common from './common.js'

export default {
	dbName() {
		return `ycim${common.loginUser.Id}`;
	},
	dbPath() {
		return `_doc/${this.dbName()}.db`;
	},
	//创建表
	createTables() {
		//表，type: 1:个人消息,2:群组消息，3:系统消息
		let sql =
			'create table if not exists chatlist(id integer NOT NULL PRIMARY KEY,other int,senderId int,type integer,time timestamp,messageType varchar(20),content text,property varchar(50),read BOOLEAN(2),serverId int, state int);'
		this.execSql(sql).catch(e => {
			setTimeout(() => {
				plus.runtime.quit();
			}, 500);
		});
	},
	//查询数据库状态是否打开
	isOpenDatabase() {
		return plus.sqlite.isOpenDatabase({
			name: this.dbName(),
			path: this.dbPath()
		});
	},
	//关闭数据库
	closeDatabase() {
		if (!this.isOpenDatabase()) {
			return Promise.resolve();
		}
		return new Promise((res, rej) => {
			plus.sqlite.closeDatabase({
				name: this.dbName(),
				success() {
					res();
				},
				fail(e) {
					rej(e);
				}
			})
		});
	},
	//打开数据库
	async openDatabase() {
		if (this.isOpenDatabase()) {
			return Promise.resolve();
		}
		return await new Promise((res, rej) => {
			plus.sqlite.openDatabase({
				name: this.dbName(),
				path: this.dbPath(),
				success() {
					res();
				},
				fail(e) {
					if (e.code == -1402) {
						res();
						return;
					}
					rej(e);
				}
			});
		});
	},
	//执行SQL
	async execSql(sql) {
		try {
			await this.openDatabase();
			return await new Promise((res, rej) => {
				plus.sqlite.executeSql({
					name: this.dbName(),
					sql,
					success(e) {
						res(e);
					},
					fail(e) {
						uni.showToast({
							title: e.message,
							icon: 'none'
						})
						rej(e);
					}
				});
			});
		} catch (e) {
			console.log('执行异常', e, sql);
			return Promise.reject(e);
		} finally {
			//await this.closeDatabase();
		}
	},
	//查询SQL
	async selectSql(sql) {
		try {
			await this.openDatabase();
			return await new Promise((res, rej) => {
				plus.sqlite.selectSql({
					name: this.dbName(),
					sql,
					success(e) {
						res(e);
					},
					fail(e) {
						uni.showToast({
							title: e.message,
							icon: 'none'
						})
						rej(e);
					}
				});
			});
		} catch (e) {
			console.log('查询异常', e);
			return Promise.reject(e);
		} finally {
			//await this.closeDatabase();
		}
	},
	//获取聊天记录
	async getHistoryChatList(data) {
		data.time = data.time || new Date(3333, 1, 1);
		data.count = data.count || 20;
		const count = data.count;
		data.count++;
		data = await this.selectSql(
			`select * from chatlist where other = ${data.other} and type = ${data.type} and time < '${data.time.format('yyyy/MM/dd hh:mm:ss:S')}' order by time desc limit ${data.count}`
		);
		let hasMore = false;
		if (data.length > count) {
			hasMore = true;
			data.pop();
		}
		return {
			data: data,
			hasMore
		};
	},
	//获取最新的聊天记录
	async getNewestChatMessage() {
		let [count, max] = await Promise.all([
			this.selectSql("select count(1) count,type,other from chatlist where read = 'false' group by type,other"),
			this.selectSql(
				'select max(time) time,id,other,read,type,messageType,content,0 msgcount,state from chatlist group by other,type order by time desc'
			)
		]);
		max.forEach(item => {
			let d = count.find(c => c.other == item.other && c.type == item.type);
			d && (item.msgcount = d.count);
		});
		return max;
	},
	//插入新消息
	insertNewMessage(msg) {
		msg = common.deepClone(msg);
		msg = Object.assign({
			property: '',
			serverId: 0
		}, msg);
		if (typeof msg.property === 'object') {
			msg.property = JSON.stringify(msg.property);
		}
		msg.time = common.formatDate(msg.time, 'yyyy/MM/dd hh:mm:ss:S');
		msg.content = common.replaceAll(msg.content || '', "'", "''");
		let sql = common.format(
			"insert into chatlist(id,other,senderId,time,type,messageType,property,read,content,state,serverId)values({0},{1},{2},'{3}',{4},'{5}','{6}','{7}','{8}',{9},{10})",
			msg.id, msg.other, msg.senderId, msg.time, msg.type, msg.messageType, msg.property, msg.read, msg.content,
			msg.state, msg.serverId);
		sql = sql.replace(/\\/g, '\\\\');
		return this.execSql(sql);
	},
	//批量插入新消息
	insertNewMessageBatch(msgs) {
		if (!Array.isArray(msgs) || msgs.length == 0) {
			return Promise.reject('没有要保存的数据');
		}
		let sql = 'insert into chatlist(id,other,senderId,time,type,messageType,property,read,content,state,serverId)';
		msgs = common.deepClone(msgs, []);
		for (let msg of msgs) {
			msg = Object.assign({
				property: '',
				serverId: 0
			}, msg);
			msg.time = common.formatDate(msg.time, 'yyyy/MM/dd hh:mm:ss:S');
			msg.content = common.replaceAll(msg.content || '', "'", "''");
			if (typeof msg.property === 'object') {
				msg.property = JSON.stringify(msg.property);
			}
			sql += " select {0},{1},{2},'{3}',{4},'{5}','{6}','{7}','{8}',{9},{10} union".format(msg.id, msg.other, msg.senderId,
				msg.time, msg.type, msg.messageType, msg.property, msg.read, msg.content, msg.state, msg.serverId);
		}
		sql = sql.replace(/\\/g, '\\\\');
		return this.execSql(sql.slice(0, -5));
	},
	//获取最大ID
	async getMaxId() {
		const [{
			id = 1
		} = {
			id: 1
		}] = await this.selectSql(`select max(id) id from chatlist`);
		return id;
	},
	//修改Read状态
	updateRead(data) {
		return this.execSql(
			`update chatlist set read = '${data.read}' where type = ${data.type} and other = ${data.other} and messageType <> 'Voice'`
		);
	},
	//修改视频状态
	updateVideoState(data) {
		if (typeof data.property === 'object') {
			data = common.deepClone(data);
			data.property = JSON.stringify(data.property);
		}
		return this.execSql(
			`update chatlist set content = '${data.content}',state = ${data.state},property = '${data.property}' where id = ${data.id}`
		);
	},
	//根据ID设置消息已读
	setReadById(data) {
		return this.execSql("update chatlist set read = 'true' where id = " + data);
	},
	//设置文件路径
	setFilePath(data) {
		return this.execSql("update chatlist set content = '{0}',state = 1 where id = {1}".format(data.content, data.id));
	},
	//删除消息
	deleteMessage(data) {
		return this.execSql('delete from chatlist where id = ' + data);
	},
	//根据服务ID删除消息
	deleteMessageByServerId(data) {
		return this.execSql('delete from chatlist where serverId = ' + data);
	},
	//根据好友ID删除消息
	deleteMessageByOther(data) {
		return this.execSql(`delete from chatlist where other = ${data.other} and type = ${data.type}`);
	},
	//根据不在范围的ID删除消息
	deleteMessagesByNotIn(data) {
		if (data.others.length < 1) {
			return Promise.resolve();
		}
		return this.execSql(`delete from chatlist where other not in(${data.others.join(',')}) and type = ${data.type}`);
	},
	//获取未读数
	getUnreadCount({
		other,
		type
	}) {
		return this.selectSql(
			`select count(1) count from chatlist where other = ${other} and type = ${type} and read = 'false'`);
	},
	//根据用户获取最新消息数据
	async getNewestMessageByUser({
		other,
		type
	}) {
		const [
			[{
				count
			}],
			[data]
		] = await Promise.all([
			this.selectSql(
				`select count(1) count from chatlist where read = 'false' and other = ${other} and type = ${type}`),
			this.selectSql(
				`select max(time) time,id,other,type,messageType,content from chatlist where other = ${other} and type = ${type}`
			)
		]);
		data.msgcount = count;
		return data;
	},
	//根据关键字搜索消息
	async getMessageByKeywords(data) {
		let condition = '';
		let limit = '';
		if (data.other) {
			condition = ` other = ${data.other} and`
		}
		if (data.type) {
			condition += ` type = ${data.type} and`;
		}
		if (data.time) {
			data.time = common.parseDate(data.time);
			condition += ` time > '${data.time.format("yyyy/MM/dd hh:mm:ss:S")}' and`;
		}
		if (data.messageType) {
			condition += ` messageType = '${data.messageType}' and`;
		}
		if (data.msg) {
			condition += ` content like '%${data.msg.replaceAll("'", "''")}%' and`;
		}
		if (data.count) {
			limit = ` limit ${data.count + 1}`;
		}
		data.orderby = data.orderby || 'desc';
		const sql = `select * from chatlist where${condition} 1 = 1 order by time ${data.orderby}${limit}`;
		if (undefined == data.count) {
			return this.selectSql(sql);
		} else {
			const list = await this.selectSql(sql);
			return {
				hasMore: list.length > data.count,
				data: list.slice(0, data.count)
			};
		}
	},
	//根据时间获取前后定量的数据
	async getBAMessageByTime(data) {
		if (data.time) {
			const time = common.parseDate(data.time).format("yyyy/MM/dd hh:mm:ss:S");
			const [before, after] = await Promise.all([
				this.selectSql(
					`select id from chatlist where time < '${time}' and other = ${data.other} and type = ${data.type} limit 1`
				),
				this.selectSql(
					`select * from chatlist where time >= '${time}' and other = ${data.other} and type = ${data.type} order by time limit ${data.count + 1}`
				)
			]);
			return {
				before: before.length > 0,
				after: after.length > data.count,
				data: after.slice(0, data.count)
			};
		} else if (data.date) {
			const date = common.parseDate(data.date);
			const start = date.format("yyyy/MM/dd");
			date.setDate(date.getDate() + 1);
			const end = date.format("yyyy/MM/dd");
			const [before, list, after] = await Promise.all([
				this.selectSql(
					`select id from chatlist where time < '${start}' and other = ${data.other} and type = ${data.type} limit 1`
				),
				this.selectSql(
					`select * from chatlist where time >= '${start}' and time < '${end}' and other = ${data.other} and type = ${data.type} order by time`
				),
				this.selectSql(
					`select id from chatlist where time >= '${end}' and other = ${data.other} and type = ${data.type} limit 1`
				)
			]);
			return {
				before: before.length > 0,
				after: after.length > 0,
				data: list
			};
		}
	},
	//根据关键字搜索消息总数
	getMessageCountByKeywords({
		msg,
		count
	}) {
		return this.selectSql(
			`select count(1) count,other,type from chatlist where messageType = 'Text' and content like '%${msg.replaceAll("'", "''")}%' group by other,type limit ${count}`
		);
	},
	//获取消息日期
	getMessageDateList({
		other,
		type
	}) {
		return this.selectSql(`select time from chatlist where type = ${type} and other = ${other} order by time`);
	},
	//查找图片及视频
	searchImageAndVideo({
		other,
		type
	}) {
		return this.selectSql(
			`select * from chatlist where (messageType = 'Image' or messageType = 'Video') and other = ${other} and type = ${type} order by time desc`
		);
	},
	//获取非文字消息
	getUntextMsg({
		other,
		type
	}) {
		return this.selectSql(
			`select content from chatlist where messageType != 'Text' and other = ${other} and type = ${type}`);
	},
	//根据服务ID获取消息
	getMessageByServerId(serverId, type) {
		return this.selectSql(`select * from chatlist where serverId = ${serverId} and type = ${type}`);
	}
}
